在開始講重構前,先來講個小故事:
臺中都會區鐵路高架捷運化計畫目前豐原到大慶的高架化工程已完成九成左右了。以下撇開政治因素與技術細節,純粹就維基資料來討論鐵路的規劃。
鐵路的功用,正是讓電車能在上面跑。但鐵路不管在平面或是高架,電車都能跑,為何還要多此一舉把平面變成高架?主要原因是,平面鐵路穿越台中,會造成前後站發展不均;鐵路與道路交錯點需要平交道,尖鋒時間容易造成交通壅塞;除此之外,另有預算增設五個區間通勤車站。
奇怪?既然會有這些問題或需求,又為何不一開始直接高架蓋好蓋滿?這又有幾種原因:
以上是筆者合理推測,但畢竟不是鐵路系,真實情況歡迎留言回應
因此,當初平面鐵路的規劃並沒有問題,而是隨著時間推演與環境變化,平面鐵路漸漸不符合需求,才會需要進行鐵路高架化。
重構一詞,如同 DevOps 或 Agile ,大家對它的認知都有點不一樣,有的人認為是砍掉重練、也有人說是效能優化。
一位知名的軟體工程大師-- Martin Fowler ,它寫了一本書就叫 Refactoring - Improving the Design of Existing Code (中譯「重構:改善即有程式的設計」)
在這本書裡, Martin 是這樣定義重構的:
Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.
中譯版的翻譯如下:
在不改變程式碼外在行為的前提下,對程式碼做出修改,以改進程式的內部結構。
重構就很像鐵路高架化一樣,它並不會改動原有功能,而是改進設計。程式原本跑好好的,哪會有人閒閒沒事去動它。但遇到業務需求需要修改程式,也只能跳下去修改,而且還不準改壞。
有維護經驗的軟體工程師都知道,遇到好改的程式碼是要看人品的,除了前人設計好之外,業務需求也剛好落在預期更動範圍內,程式碼才會好改。人品不好,就有機會看到設計不良、難以修改的程式碼,加上跟原本設計不搭的業務需求。
上述兩種狀況都很極端,以一個常態分佈的狀況下,通常會是一個設計還算可以的程式,但開始難以應付新需求。可能程式是自己一手維護,但同時也隱約感覺到它出現了瓶頸。
由前面的故事可以了解,現實生活中我們最常遇到的是:現有設計無法輕易的滿足業務需求,這時有幾種選擇:
第一、解決不了需求,那只好解決提出需求的人。但通常有很高的機率被提出需求的人(如老闆)解決掉。
第二、在現有設計下,硬是把跟設計不合的功能實作出來。這個方法又稱為 workaround ,因省下重新設計的時間,通常都能以較短的時間完成需求,但這些省下的時間都會在未來付出代價。
第三、山不轉,路轉!那我們把程式改成「可以輕易滿足需求的設計」就好了呀!這方法跟 workaround 剛好相反,當下花時間設計,但會省下未來修改的時間。是的,這就是本次鐵人賽的主題--重構!
講了這麼多,為何我們需要重構?甚至還有專門的書在說明重構的技巧?
環境會變,需求也會跟著變,沒有人能保證鐵路不會變高架,也無法保證自己的程式碼不需要修改。重構技巧可以應付改變,也能提高程式碼品質,讓程式碼更好維護,這就是為何我們會需要重構!